package com.blackcat.demo.interceptor;

import lombok.extern.slf4j.Slf4j;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import static org.springframework.util.ObjectUtils.isEmpty;

/**
 * <p> 描述 ：拦截器
 * @author : blackcat
 * @date : 2020/5/20 14:28
 *
 * 类似 面向切面编程 中的 切面 和 通知，我们通过 动态代理 对一个 service() 方法添加 通知 进行功能增强。比如说在方法执行前进行 初始化处理，在方法执行后进行 后置处理。
 * 拦截器 的思想和 AOP 类似，区别就是 拦截器 只能对 Controller 的 HTTP 请求进行拦截。
 *
 * 拦截器在做安全方面用的比较多，比如终止一些流程
 * 拦截器 Interceptor 只对 Handler 生效。Spring MVC 会为 Controller 中的每个 请求方法 实例化为一个 Handler对象，
 * 由 HandlerMapping 对象路由请求到具体的 Handler，然后由 HandlerAdapter 通过反射进行请求 处理 和 响应，这中间就穿插着 拦截处理。
 */
@Slf4j
public class FirstIndexInterceptor implements HandlerInterceptor {

    /**
     * <p> 描述 : 在请求处理之前进行调用（Controller方法调用之前
     * @author : blackcat
     * @date  : 2020/5/20 14:32
     *
     * controller 接收请求、处理 request 之前执行，返回值为 boolean，
     * 返回值为 true 时接着执行 postHandle() 和 afterCompletion() 方法；
     * 如果返回 false 则 中断 执行。
    */
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        log.info("进入preHandle");
        String interceptor = request.getParameter("interceptor1");
        if (isEmpty(interceptor)) {
            response.getWriter().println("FirstIndexInterceptor preHandle() \"interceptor1\"");
            return false;
        }
        return true;
    }

    /**
     * <p> 描述 : 请求处理之后进行调用，但是在视图被渲染之前（Controller方法调用之后）
     * @author : blackcat
     * @date  : 2020/5/20 14:33
    */
    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
        log.info("进入postHandle");
    }

    /**
     * <p> 描述 : 在整个请求结束之后被调用，也就是在DispatcherServlet 渲染了对应的视图之后执行（主要是用于进行资源清理工作）
     * @author : blackcat
     * @date  : 2020/5/20 14:33
    */
    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        log.info("进入afterCompletion");
    }
}
